package com.yn.pet.controller.app.biz;



import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Sets;
import com.yn.common.utils.DateUtils;
import com.yn.common.utils.bean.BeanUtils;
import com.yn.pet.bus.entity.*;
import com.yn.pet.controller.pc.request.FenceAlarmRecordRequest;
import com.yn.pet.controller.pc.response.FenceAlarmQueryResponse;
import com.yn.pet.controller.pc.response.OtherAlarmQueryResponse;

import com.yn.pet.entity.AppUser;
import com.yn.pet.bus.entity.DeviceInfo;
import com.yn.pet.entity.Pet;
import com.yn.pet.enums.FenceAlarmTypeEnum;
import com.yn.pet.enums.OtherAlarmTypeEnum;
import com.yn.pet.service.*;
import com.yn.pet.util.AppTokenUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class AlarmRecordBizService {

    private final GenFenceService fenceService;
    private final PetService petService;
    private final DeviceSimService deviceSimService;
    private final DeviceInfoService deviceInfoService;
    private final GenFenceAlarmService fenceAlarmService;
    private final LocationRealtimeService locationRealtimeService;
    private final AlarmRecordService alarmRecordService;

    /**
     * 获取围栏警告记录列表
     * @param request 请求参数
     * @return IPage<FenceAlarmQueryResponse>
     */
    public IPage<FenceAlarmQueryResponse> listFenceAlarmRecord(FenceAlarmRecordRequest request) {
        int currentPage = 1;
        int pageSize = 10;
        if (request.getCurrentPage() != null) {
            currentPage = request.getCurrentPage();
        }
        if (request.getPageSize() != null) {
            pageSize = request.getPageSize();
        }
        //获取当前登录用户id
        AppUser user = AppTokenUtil.getAppUser();
        if(user==null){
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = user.getAppUserId();

        //构建查询条件
        Set<Long> finalDeviceIds=new HashSet<>();
        String imei = request.getKeyword();
       if(StringUtils.isNotBlank(imei)){
           LambdaQueryWrapper<DeviceInfo> deviceInfoQuery = Wrappers.lambdaQuery();
           deviceInfoQuery.like(DeviceInfo::getImei, imei);
           DeviceInfo deviceInfo = deviceInfoService.getOne(deviceInfoQuery);
           if(deviceInfo==null){
               return new Page<>();
           }
           finalDeviceIds.add(deviceInfo.getDeviceId());
       }else {
           finalDeviceIds = getDeviceSets(null, userId);
       }
        if (CollectionUtils.isEmpty(finalDeviceIds)) {
            return new Page<>();
        }

        //构建查询条件
        LambdaQueryWrapper<GenFenceAlarm> lambdaQuery = Wrappers.lambdaQuery();
        String alarmTypes = request.getAlarmType();
        if (StringUtils.isNotBlank(alarmTypes)) {
            String[] alarmTypeArray = alarmTypes.split(",");
            Set<Integer> alarmTypeSet = Sets.newHashSet();
            for (String alarmType : alarmTypeArray) {
                alarmTypeSet.add(Integer.parseInt(alarmType));
            }
            lambdaQuery.in(GenFenceAlarm::getAlarmType, alarmTypeSet);
        }
        lambdaQuery.orderByDesc(GenFenceAlarm::getAlarmTime)
                .in(GenFenceAlarm::getDeviceId, finalDeviceIds);
        if (StringUtils.isNotBlank(request.getStartTime()) && StringUtils.isNotBlank(request.getEndTime())) {
            Date beginTime = DateUtils.parseDate(request.getStartTime());
            Date endTime = DateUtils.parseDate(request.getEndTime());
            lambdaQuery.between(GenFenceAlarm::getAlarmTime, beginTime, endTime);
        }
        Page<GenFenceAlarm> page = fenceAlarmService.page(new Page<>(currentPage, pageSize), lambdaQuery);
        List<GenFenceAlarm> alarmList = page.getRecords();
        if (CollectionUtils.isEmpty(alarmList)) {
            return new Page<>();
        }
        return page.convert(alarm -> {
            FenceAlarmQueryResponse response = new FenceAlarmQueryResponse();
            response.setAlarmId(alarm.getAlarmId());

            response.setAlarmTime(alarm.getAlarmTime());
            response.setAlarmType(alarm.getAlarmType());
            response.setAlarmTypeStr(FenceAlarmTypeEnum.getByCode(alarm.getAlarmType()).getName());
            //围栏信息
            response.setFenceId(alarm.getFenceId());
            log.info("围栏id:{}", alarm.getFenceId());
            GenFence fenceInfo = fenceService.selectFenceById(alarm.getFenceId());
            response.setFenceName(fenceInfo.getFenceName());
            //设备信息
            response.setDeviceId(alarm.getDeviceId());
            LambdaQueryWrapper<DeviceInfo> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(DeviceInfo::getDeviceId, alarm.getDeviceId());
            DeviceInfo deviceInfo = deviceInfoService.getOne(queryWrapper);
            response.setDeviceName(deviceInfo.getDeviceName());
            response.setImei(deviceInfo.getImei());
            //位置信息
            response.setLocationId(alarm.getLocationId());
            Long locationId = alarm.getLocationId();
            LocationRealtime realtime = locationRealtimeService.getByLocationId(alarm.getLocationId());
            if(realtime==null){
                log.error("设备没有定位信息,locationId:{}", locationId);
            }else{
                response.setLongitude(realtime.getLongitude());
                response.setLatitude(realtime.getLatitude());
                response.setDetailedLocation(realtime.getDetailedLocation());
                if(realtime.getSpeed()>0){
                    response.setSpeed(realtime.getSpeed()/10);
                }else{
                    response.setSpeed(0);
                }
            }
            return response;
        });
    }

    /**
     * 获取其他警告记录列表
     * @param request 请求参数
     * @return IPage<OtherAlarmQueryResponse>
     */
    public IPage<OtherAlarmQueryResponse> listOtherAlarmRecord(FenceAlarmRecordRequest request) {
        int currentPage = 1;
        int pageSize = 10;
        if (request.getCurrentPage() != null) {
            currentPage = request.getCurrentPage();
        }
        if (request.getPageSize() != null) {
            pageSize = request.getPageSize();
        }
        //获取当前登录用户id
        AppUser user = AppTokenUtil.getAppUser();
        if(user==null){
            throw new RuntimeException("当前用户未登录");
        }
        Long userId = user.getAppUserId();
        //构建查询条件
       String imei = request.getKeyword();
       Set<Long> finalDeviceIds=new HashSet<>();
        if(StringUtils.isNotBlank(imei)){
            LambdaQueryWrapper<DeviceInfo> deviceInfoQuery = Wrappers.lambdaQuery();
            deviceInfoQuery.like(DeviceInfo::getImei, imei);
            DeviceInfo deviceInfo = deviceInfoService.getOne(deviceInfoQuery);
            if(deviceInfo==null){
                return new Page<>();
            }
            finalDeviceIds.add(deviceInfo.getDeviceId());
        }else {
            finalDeviceIds = getDeviceSets(null, userId);
        }
        if (CollectionUtils.isEmpty(finalDeviceIds)) {
            return new Page<>();
        }
        LambdaQueryWrapper<AlarmRecord> lambdaQuery = Wrappers.lambdaQuery();
        String alarmTypes = request.getAlarmType();
        if (StringUtils.isNotBlank(alarmTypes)) {
            String[] alarmTypeArray = alarmTypes.split(",");
            Set<Integer> alarmTypeSet = Sets.newHashSet();
            for (String alarmType : alarmTypeArray) {
                alarmTypeSet.add(Integer.parseInt(alarmType));
            }
            lambdaQuery.in(AlarmRecord::getType, alarmTypeSet);
        }
        lambdaQuery.orderByDesc(AlarmRecord::getCreateTime)
                .in(AlarmRecord::getDeviceId, finalDeviceIds);
        if (StringUtils.isNotBlank(request.getStartTime()) && StringUtils.isNotBlank(request.getEndTime())) {
            Date beginTime = DateUtils.parseDate(request.getStartTime());
            Date endTime = DateUtils.parseDate(request.getEndTime());
            lambdaQuery.between(AlarmRecord::getCreateTime, beginTime, endTime);
        }
        Page<AlarmRecord> page = alarmRecordService.page(new Page<>(currentPage, pageSize), lambdaQuery);
        if (CollectionUtils.isEmpty(page.getRecords())) {
            return new Page<>();
        }
        return page.convert(record -> {
            OtherAlarmQueryResponse response = new OtherAlarmQueryResponse();
            BeanUtils.copyProperties(record, response);
            response.setAlarmType(record.getType());
            response.setAlarmTypeStr(OtherAlarmTypeEnum.getByCode(record.getType()).getName());
            //报警事件
            response.setAlarmTime(record.getCreateTime());
            response.setAlarmId(record.getId());
            //设备信息
            LambdaQueryWrapper<DeviceInfo> queryWrapper = Wrappers.lambdaQuery();
            queryWrapper.eq(DeviceInfo::getDeviceId, record.getDeviceId());
            DeviceInfo deviceInfo = deviceInfoService.getOne(queryWrapper);
            response.setDeviceName(deviceInfo.getDeviceName());
            response.setImei(deviceInfo.getImei());
            //位置信息
            LocationRealtime realtime = locationRealtimeService.getByLocationId(record.getLocationId());
            response.setLongitude(realtime.getLongitude());
            response.setLatitude(realtime.getLatitude());
            response.setDetailedLocation(realtime.getDetailedLocation());
            if(realtime.getSpeed()>0){
                response.setSpeed(realtime.getSpeed()/10);
            }else{
                response.setSpeed(realtime.getSpeed());
            }
            return response;
        });
    }

    /**
     * 获取设备ID集合
     * @param keyword 关键字
     * @param userId 用户id
     * @return 设备ID集合
     */
    public Set<Long> getDeviceIds( String keyword,Long userId){
        Set<Long> finalDeviceIds;
        if (StringUtils.isNotBlank(keyword)) {
            Set<Long> deviceIdSet = new HashSet<>();
            //1. 可能关键字是手机号， 则根据手机号模糊查询设备id
            LambdaQueryWrapper<DeviceSim> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.like(DeviceSim::getPhoneNumber, keyword);
            List<DeviceSim> list = deviceSimService.list(lambdaQuery);
            if (!CollectionUtils.isEmpty(list)) {
                deviceIdSet = list.stream().map(DeviceSim::getDeviceId).collect(Collectors.toSet());
            }
            //根据关键字从电话绑定表获取的deviceId集合里可能有不是该用户绑定的设备，所以后面要进行过滤
            if (!CollectionUtils.isEmpty(deviceIdSet)) {
                List<Pet> pets = petService.getByDeviceIdsAndUserId(deviceIdSet, userId);
                if (!CollectionUtils.isEmpty(pets)) {
                    deviceIdSet = pets.stream().map(Pet::getDeviceId).collect(Collectors.toSet());
                }else{
                    deviceIdSet = Sets.newHashSet();
                }
            }

            //2. 可能关键字是设备号，则从设备表模糊查询获取
            List<DeviceInfo> deviceInfos = deviceInfoService.listLikeImei(keyword);
            //获取设备id集合
            Set<Long> imeiDeviceIds = new HashSet<>();
            if (!CollectionUtils.isEmpty(deviceInfos)) {
                imeiDeviceIds = deviceInfos.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toSet());
            }
            if (!CollectionUtils.isEmpty(imeiDeviceIds)) {
                List<Pet> pets = petService.getByDeviceIdsAndUserId(imeiDeviceIds, userId);
                if (!CollectionUtils.isEmpty(pets)) {
                    imeiDeviceIds = pets.stream().map(Pet::getDeviceId).collect(Collectors.toSet());
                }else{
                    imeiDeviceIds=Sets.newHashSet();
                }
            }
            //求deviceIdSet和imeiDeviceIds的并集
            finalDeviceIds = Sets.union(deviceIdSet, imeiDeviceIds);

            //3.如果关键字是设备名称，则查询设备名称
            List<DeviceInfo> likeDeviceName = deviceInfoService.listLikeDeviceName(keyword);
            Set<Long> nameDeviceIds = new HashSet<>();
            if (!CollectionUtils.isEmpty(likeDeviceName)) {
                nameDeviceIds = likeDeviceName.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toSet());
            }
            if (!CollectionUtils.isEmpty(nameDeviceIds)) {
                List<Pet> pets = petService.getByDeviceIdsAndUserId(nameDeviceIds, userId);
                if (!CollectionUtils.isEmpty(pets)) {
                    nameDeviceIds = pets.stream().map(Pet::getDeviceId).collect(Collectors.toSet());
                }
            }
            //求finalDeviceIds和nameDeviceIds的并级
            finalDeviceIds = Sets.union(finalDeviceIds, nameDeviceIds);
        } else {
            List<Pet> pets = petService.listByUserId(userId);
            if (CollectionUtils.isEmpty(pets)) {
                finalDeviceIds=Sets.newHashSet();
            }else{
                //获取设备id集合
                finalDeviceIds = pets.stream().map(Pet::getDeviceId).collect(Collectors.toSet());
            }
        }
        return finalDeviceIds;
    }

    /**
     * 获取设备ID集合
     * @param keyword 关键字
     * @param userId 用户id
     * @return 设备ID集合
     */
    public Set<Long> getDeviceSets( String keyword,Long userId){
        Set<Long> finalDeviceIds = new HashSet<>();

        List<Pet> pets = petService.listByUserId(userId);
        if (CollectionUtils.isEmpty(pets)) {
            return Collections.emptySet();
        }
        Set<Long> deviceIds = pets.stream().map(Pet::getDeviceId).collect(Collectors.toSet());
        if (StringUtils.isNotBlank(keyword)) {
            //1. 可能关键字是手机号， 则根据手机号模糊查询设备id
            Set<Long> phoneDeviceIds = new HashSet<>();
            LambdaQueryWrapper<DeviceSim> lambdaQuery = Wrappers.lambdaQuery();
            lambdaQuery.like(DeviceSim::getPhoneNumber, keyword);
            lambdaQuery.in(DeviceSim::getDeviceId,deviceIds );
            List<DeviceSim> list = deviceSimService.list(lambdaQuery);
            if (!CollectionUtils.isEmpty(list)) {
                phoneDeviceIds = list.stream().map(DeviceSim::getDeviceId).collect(Collectors.toSet());
            }
            //2. 可能关键字是设备号，则从设备表模糊查询获取
            LambdaQueryWrapper<DeviceInfo> lambdaQueryImei = Wrappers.lambdaQuery();
            lambdaQueryImei.like(DeviceInfo::getImei, keyword);
            lambdaQueryImei.in(DeviceInfo::getDeviceId,deviceIds);
            List<DeviceInfo> deviceInfos = deviceInfoService.list(lambdaQueryImei);
            //获取设备id集合
            Set<Long> imeiDeviceIds = new HashSet<>();
            if (!CollectionUtils.isEmpty(deviceInfos)) {
                imeiDeviceIds = deviceInfos.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toSet());
            }
            //求phoneDeviceIds和imeiDeviceIds的并集
            finalDeviceIds = Sets.union(phoneDeviceIds, imeiDeviceIds);

            //3.如果关键字是设备名称，则查询设备名称
            LambdaQueryWrapper<DeviceInfo> lambdaQueryName = Wrappers.lambdaQuery();
            lambdaQueryName.like(DeviceInfo::getDeviceName, keyword);
            lambdaQueryName.in(DeviceInfo::getDeviceId,deviceIds);
            List<DeviceInfo> likeDeviceName = deviceInfoService.list(lambdaQueryName);
            Set<Long> nameDeviceIds = new HashSet<>();
            if (!CollectionUtils.isEmpty(likeDeviceName)) {
                nameDeviceIds = likeDeviceName.stream().map(DeviceInfo::getDeviceId).collect(Collectors.toSet());
            }
            //求finalDeviceIds和nameDeviceIds的并级
            finalDeviceIds = Sets.union(finalDeviceIds, nameDeviceIds);
        }else {
            finalDeviceIds = deviceIds;
        }
        return finalDeviceIds;
    }


    /**
     * 删除围栏告警记录
     * @param alarmId  警告id
     * @return
     */
    public void removeFenceAlarmRecord(Long alarmId) {
        LambdaUpdateWrapper<GenFenceAlarm> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(GenFenceAlarm::getAlarmId, alarmId);
        fenceAlarmService.remove(wrapper);
    }

    /**
     * 批量删除围栏告警记录
     * @param alarmIdSet 围栏告警id集合
     * @return
     */
    public void removeFenceAlarmRecordBatch(Set<Long> alarmIdSet) {
        LambdaUpdateWrapper<GenFenceAlarm> wrapper = Wrappers.lambdaUpdate();
        wrapper.in(GenFenceAlarm::getAlarmId, alarmIdSet);
        fenceAlarmService.remove(wrapper);
    }

    /**
     * 删除其他告警记录
     * @param id  其他警告id
     * @return
     */
    public void removeOtherAlarmRecord(Long id) {
        LambdaUpdateWrapper<AlarmRecord> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(AlarmRecord::getId, id);
        alarmRecordService.remove(wrapper);
    }

    /**
     * 批量删除其他告警记录
     * @param idSet 其他告警id集合
     * @return
     */
    public void removeOtherAlarmRecordBatch(Set<Long> idSet) {
        LambdaUpdateWrapper<AlarmRecord> wrapper = Wrappers.lambdaUpdate();
        wrapper.in(AlarmRecord::getId, idSet);
        alarmRecordService.remove(wrapper);
    }
}
